package data
{
	import com.maclema.mysql.MySqlToken;
	import com.maclema.mysql.ResultSet;
	
	import controls.DataRequestor;
	import controls.events.ServiceEvent;
	
	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;
	
	import mx.collections.ArrayCollection;
	
	public class Course extends EventDispatcher
	{
		// --------------------- Public Variables --------------------- //
		public var title:String;
		public var prereq:int;
		public var coreq:int;
		public var subject:String;
		public var courseNumber:int;
		public var sections:Array;
		public var credits:int;
		public var id:int;
		public var gpa:Number;
		// --------------------- Public Variables --------------------- //
		
		// --------------- Private Variables --------------- //
		private var requestor:DataRequestor = DataRequestor.instance;
		private var pendingRequestCount:int;
		private var pending:Dictionary;
		// --------------- END Private Variables ------------------- //
		
		public function Course(row:Object = null)
		{
			pending = new Dictionary();
			pendingRequestCount = 0;
			gpa = 2.5;
			sections = [];
			if(row != null)
			{
				credits = row.Credits;
				id = row.UID;
				title = row.Course;
				if(row.hasOwnProperty('coreq') && row.coreq != 0)
					this.coreq = row.coreq;
				if(row.hasOwnProperty('prereq') && row.prereq != 0)
					this.prereq = row.prereq;
				
				getSectionInformation();
				getCourseGPA();
			}
		}
		
		// ------------- Data Fetching and Parsing ------------- //
		public function getCourseGPA():void
		{
			requestor.getCourseGPA(this, parseGPA);
		}
		
		public function getSectionInformation():void
		{
			requestor.getCourseSections(this, parseSections);
		}
		
		private function parseGPA(sqlData:Object, token:MySqlToken):void
		{
			var avgGPA:Number = 0;
			
			var rs:ResultSet = sqlData as ResultSet;
			for each(var row:Object in rs.getRows())
				avgGPA += row.GPA;
			avgGPA /= rs.getRows().length;
			
			gpa = avgGPA;
			
			getSectionProfGPAs();
		}
		
		private function getSectionProfGPAs():void
		{
			for each(var section:ClassSection in sections)
			{
				section.addEventListener(ServiceEvent.COURSES_LOADED, onSectionReady);
				if(section.professor == null)
					section.pendingRequest = true;
				else
					section.professor.getCourseGPAInfo(title);
			}
		}
		
		private function onSectionReady(evt:ServiceEvent):void
		{
			var sect:ClassSection = evt.data as ClassSection;
			if(sect.pendingRequest && sect.professor.grades.length == 0)
				sect.professor.getCourseGPAInfo(title);
			else
				sect.pendingRequest = false;
				
			pendingRequestCount --;
			pending[sect.id] = false;
			if(pendingRequestCount == 0)
				this.dispatchEvent(new ServiceEvent(ServiceEvent.COURSES_LOADED, this));
		}
		
		private function parseSections(sqlData:Object, token:MySqlToken):void
		{
			var rs:ResultSet = sqlData as ResultSet;
			
			var rows:ArrayCollection = rs.getRows();
			pendingRequestCount = rows.length;
			
			for each(var row:Object in rs.getRows())
			{
				var sect:ClassSection = new ClassSection(row)
				sections.push(sect);
				pending[sect.id] = sect;
			}
				
			if(pendingRequestCount == 0)
				this.dispatchEvent(new ServiceEvent(ServiceEvent.COURSES_LOADED, this));
		}
		// ------------- END Data Fetching and Parsing ------------- //
	}
}